<script setup>
import { nextTick, onMounted, onUpdated, ref, watch } from 'vue';
import { getCurrentInstance } from 'vue';
import { MdEditor, MdCatalog, NormalToolbar } from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
import { uploadArticleContentImgService } from '@/api/forumArticle';
// import { Picker } from 'emoji-mart-vue-fast';
// import 'emoji-mart-vue-fast/css/emoji-mart.css';

// Vue实例
const { proxy } = getCurrentInstance()

// 父级传递过来的参数
const props = defineProps({
  modelValue: { // 文章内容
    type: String,
    default: "",
  },
  height: {
    type: Number,
    default: 600,
  }
})

// MD编辑器Ref
const editorRef = ref();

// MD编辑器ID
const editorId = ref('my-editor')

// MD编辑器内容
const text = ref();

// 全局编辑器主题 theme（支持默认和暗夜模式两种）
// const globalEditorTheme = ref(['light', 'dark']);
const globalEditorTheme = ref('light');

// 预览内容主题 previewTheme
const previewTheme = ref(['default', 'github', 'vuepress', 'mk-cute', 'smart-blue', 'cyanosis'])
const activePreviewTheme = ref('default')

// 块级代码主题 codeTheme
const codeTheme = ref(['atom', 'a11y', 'github', 'gradient', 'kimbie', 'paraiso', 'qtcreator', 'stackoverflow'])
const activeCodeTheme = ref('atom')

// 图片上传
const onUploadImg = async (files, callback) => {
  let res = await uploadArticleContentImgService({
    file: files[0]
  })
  console.log("文件上传结果", res)

  // callback 函数是MdEditor提供的回调函数
  // 将处理好的URL数组传给它，编辑器就会把这些图片插入到当前光标位置
  callback([res.data]);
}

// 目录获取
const catalogList = ref([])
const onGetCatalog = (list) => {
  catalogList.value = list;
};
// 目录展示 (使用内置MdCatalog组件)
const scrollElement = document.documentElement;

// 配置工具栏显示哪些按钮
const toolbars = [
  'bold',
  'underline',
  'italic',
  '-',
  'title',
  'strikeThrough',
  'sub',
  'sup',
  'quote',
  'unorderedList',
  'orderedList',
  'task',
  '-',
  'codeRow',
  'code',
  'link',
  'image',
  'table',
  'mermaid',
  'katex',
  // 'emoji', // 添加emoji按钮
  '-',
  'revoke',
  'next',
  'save',
  '=',
  'pageFullscreen',
  'fullscreen',
  'preview',
  'previewOnly',
  'htmlPreview',
  'catalog',
  // 'github',
];

// 表情插件
// npm install emoji-mart-vue-fast
// 插入表情
const insertEmoji = (emoji) => {
  text.value += emoji.native;
};

// 保存（ctrl + s）
const onSave = (v, h) => {
  console.log(v); // text内容

  h.then((html) => {
    console.log(html);  // html内容
  });
}

// 父级方法(子级可以调用)
const emit = defineEmits(['update:modelValue', 'setHtmlContent', 'setPreviewTheme', 'setCodeTheme'])

// MD编辑器内容变化
const handleChange = (cont) => {
  text.value = cont  // 将MD编辑器内容赋值给绑定文本对象
  console.log("MD编辑器内容变化", cont)
  emit("update:modelValue", cont) // 对应数据库中markdownContent内容
}
// MD编辑器内容对应html变化
const handleHtmlChanged = (htmlCont) => {
  console.log("MD编辑器内容对应html变化", htmlCont)
  emit("setHtmlContent", htmlCont) // 对应数据库中content内容
}

// 暴露给父组件调用的方法-------------------------------
const updateContent = () => {
  // 对应数据库中markdownContent内容
  emit("update:modelValue", text.value)
}
const updateText = (t) => {
  // 更新编辑器中文本内容text
  text.value = t
}
const updatePreviewTheme = () => {
  // 对应数据库中PreviewTheme内容
  return activePreviewTheme.value
}
const updateCodeTheme = () => {
  // 对应数据库中CodeTheme内容
  return activeCodeTheme.value
}
defineExpose({ updateContent, updateText, updatePreviewTheme, updateCodeTheme })

// 自定义编辑器主题切换图标=================================
// 太阳
const themeIcon = `
  <svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-list-tree-icon md-editor-icon">
    <circle cx="12" cy="12" r="5"></circle>
    <line x1="12" y1="1" x2="12" y2="3"></line>
    <line x1="12" y1="21" x2="12" y2="23"></line>
    <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
    <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
    <line x1="1" y1="12" x2="3" y2="12"></line>
    <line x1="21" y1="12" x2="23" y2="12"></line>
    <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
    <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
  </svg>
`;
// 月亮
const themeIcon2 = `
  <svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-list-tree-icon md-editor-icon">
    <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
  </svg>
`;
// 添加切换编辑器主题按钮
onMounted(() => {
  // 先获取右侧工具栏
  const toolbarRight = document.querySelector(".md-editor-toolbar-right")
  // 创建一个新的dom节点，用来切换主题
  const changeThemeDOM = document.createElement('div')
  // 向该dom节点添加class
  changeThemeDOM.className = 'md-editor-toolbar-item'
  // 设置dom节点title
  changeThemeDOM.title = globalEditorTheme.value === 'light' ? '切换暗黑主题' : '切换明亮主题';
  // 设置该dom节点的内容
  changeThemeDOM.innerHTML = themeIcon
  changeThemeDOM.addEventListener('click', () => {
    globalEditorTheme.value = globalEditorTheme.value === 'light' ? 'dark' : 'light';
    changeThemeDOM.innerHTML = changeThemeDOM.innerHTML === themeIcon ? themeIcon2 : themeIcon
  });
  // 追加到右侧工具栏中
  toolbarRight.appendChild(changeThemeDOM)
})


// 自定义切换预览主题功能=========================================
// 创建一个div，负责包含预览主题切换按钮和下拉框
const getPreviewThemeDiv = () => {
  const div = document.createElement('div');
  // 鼠标移入显示下拉框
  div.addEventListener('mouseenter', (e) => {
    // 切换md-editor-dropdown-hidden类名
    document.querySelectorAll('.md-editor-dropdown')[document.querySelectorAll('.md-editor-dropdown').length - 2].classList.toggle('md-editor-dropdown-hidden');
  });
  // 鼠标移出隐藏下拉框
  div.addEventListener('mouseleave', (e) => {
    // 切换md-editor-dropdown-hidden类名
    document.querySelectorAll('.md-editor-dropdown')[document.querySelectorAll('.md-editor-dropdown').length - 2].classList.toggle('md-editor-dropdown-hidden');
  });
  return div;
}
// 创建切换预览主题按钮
const createPreviewThemeButton = () => {
  const button = document.createElement('div');
  button.className = 'md-editor-toolbar-item';
  button.title = "切换预览主题";
  button.innerHTML = `
    <svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-list-tree-icon md-editor-icon">
      <path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9-4.03-9-9-9zm0 16c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7z"/>
      <circle cx="12" cy="12" r="3"/>
    </svg>
  `;
  return button;
};
// 预览主题切换菜单下拉框的HTML
const getPreviewThemeMenuHTML = () => {
  const menu = document.createElement('div');
  menu.className = 'md-editor-dropdown md-editor-dropdown-hidden my-toolbar-item';
  // menu.innerHTML = `<div class="md-editor-dropdown-overlay my-dropdown">
  //     <ul class="md-editor-menu" role="menu">
  //       <li class="md-editor-menu-item my-menu-item">123</li>
  //       <li class="md-editor-menu-item my-menu-item">456</li>
  //     </ul>
  //   </div>`;
  const _div = document.createElement('div');
  _div.className = 'md-editor-dropdown-overlay my-dropdown'
  const _ul = document.createElement('ul');
  _ul.className = 'md-editor-menu'
  for (let i = 0; i < previewTheme.value.length; i++) {
    const _li = document.createElement('li')
    _li.className = 'md-editor-menu-item my-menu-item'
    // _li.textContent = `项目 ${i}`
    _li.textContent = `${previewTheme.value[i]}`
    // 添加点击事件（修改预览主题）
    _li.addEventListener('click', () => {
      console.log("点击了", i)
      activePreviewTheme.value = previewTheme.value[i]
      emit("setPreviewTheme", previewTheme.value[i]) // 对应数据库中PreviewTheme内容
    })
    _ul.appendChild(_li)
  }
  _div.appendChild(_ul)
  menu.appendChild(_div)

  return menu;
};
// 将上述创建的三个dom挂载
onMounted(() => {
  // 先获取左侧工具栏
  const toolbarLeft = document.querySelector(".md-editor-toolbar-left")
  // 创建一个div，让按钮和下拉框都放到div中
  const div = getPreviewThemeDiv();
  // 创建主题切换按钮和下拉框
  const btn = createPreviewThemeButton()
  const menu = getPreviewThemeMenuHTML()
  // 菜单栏追加到按钮下
  // btn.appendChild(menu)
  // 追加到右侧工具栏中
  // toolbarLeft.appendChild(btn)
  // toolbarLeft.appendChild(menu)
  toolbarLeft.appendChild(div)
  div.appendChild(btn)
  div.appendChild(menu)
})


// 自定义切换代码主题功能=========================================
// 创建一个div，负责包含代码主题切换按钮和下拉框
const getCodeThemeDiv = () => {
  const div = document.createElement('div');
  // 鼠标移入显示下拉框
  div.addEventListener('mouseenter', (e) => {
    // 切换md-editor-dropdown-hidden类名
    document.querySelectorAll('.md-editor-dropdown')[document.querySelectorAll('.md-editor-dropdown').length - 1].classList.toggle('md-editor-dropdown-hidden');
  });
  // 鼠标移出隐藏下拉框
  div.addEventListener('mouseleave', (e) => {
    // 切换md-editor-dropdown-hidden类名
    document.querySelectorAll('.md-editor-dropdown')[document.querySelectorAll('.md-editor-dropdown').length - 1].classList.toggle('md-editor-dropdown-hidden');
  });
  return div;
}
// 创建切换代码主题按钮
const createCodeThemeButton = () => {
  const button = document.createElement('div');
  button.className = 'md-editor-toolbar-item';
  button.title = "切换代码主题";
  button.innerHTML = `
    <svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-list-tree-icon md-editor-icon">
      <!-- 同心圆结构 -->
      <circle cx="12" cy="12" r="8"/>
      <circle cx="12" cy="12" r="5"/>
    </svg>
  `;
  return button;
};
// 代码主题切换菜单下拉框的HTML
const getCodeThemeMenuHTML = () => {
  const menu = document.createElement('div');
  menu.className = 'md-editor-dropdown md-editor-dropdown-hidden my-toolbar-item2';
  // menu.innerHTML = `<div class="md-editor-dropdown-overlay my-dropdown">
  //     <ul class="md-editor-menu" role="menu">
  //       <li class="md-editor-menu-item my-menu-item">123</li>
  //       <li class="md-editor-menu-item my-menu-item">456</li>
  //     </ul>
  //   </div>`;
  const _div = document.createElement('div');
  _div.className = 'md-editor-dropdown-overlay my-dropdown'
  const _ul = document.createElement('ul');
  _ul.className = 'md-editor-menu'
  for (let i = 0; i < codeTheme.value.length; i++) {
    const _li = document.createElement('li')
    _li.className = 'md-editor-menu-item my-menu-item'
    // _li.textContent = `项目 ${i}`
    _li.textContent = `${codeTheme.value[i]}`
    // 添加点击事件（修改代码主题）
    _li.addEventListener('click', () => {
      console.log("点击了", i)
      activeCodeTheme.value = codeTheme.value[i]
      emit("setCodeTheme", codeTheme.value[i]) // 对应数据库中CodeTheme内容
    })
    _ul.appendChild(_li)
  }
  _div.appendChild(_ul)
  menu.appendChild(_div)

  return menu;
};
// 将上述创建的三个dom挂载
onMounted(() => {
  // 先获取左侧工具栏
  const toolbarLeft = document.querySelector(".md-editor-toolbar-left")
  // 创建一个div，让按钮和下拉框都放到div中
  const div = getCodeThemeDiv();
  // 创建主题切换按钮和下拉框
  const btn = createCodeThemeButton()
  const menu = getCodeThemeMenuHTML()
  // 菜单栏追加到按钮下
  toolbarLeft.appendChild(div)
  div.appendChild(btn)
  div.appendChild(menu)
})
</script>

<template>
  <div>
    <MdEditor ref="editorRef" :id="editorId" v-model="text" :theme="globalEditorTheme"
      :previewTheme="activePreviewTheme" :defCatalogVisible="true" :codeTheme="activeCodeTheme"
      @onUploadImg="onUploadImg" @onGetCatalog="onGetCatalog" @onSave="onSave" @onChange="handleChange"
      @onHtmlChanged="handleHtmlChanged" :style="{ height: height + 'px' }" :toolbars="toolbars">
      <!-- <template #defToolbars>
        <EmojiPicker @select="insertEmoji" />
      </template> -->
    </MdEditor>

    <!-- 目录 -->
    <!-- <MdCatalog :editorId="editorId" :scrollElement="scrollElement" :theme="globalEditorTheme[0]" /> -->
  </div>
</template>

<style scoped>
/* 调整工具栏图标大小 */
:deep(.md-editor-toolbar-wrapper .md-editor-icon) {
  font-size: 20px;
  width: 26px;
  height: 26px;
}

/* 自定义的切换预览主题按钮相关 */
/* :deep(.my-toolbar-item) {
  position: relative;
} */

/* :deep(.my-preview-theme-menu) {
  width: 100%;
  height: 200px;
  position: absolute;
  left: 0;
  top: 100%;
  background-color: black;
} */

:deep(.my-toolbar-item) {
  top: 31px;
  left: 690px;
  /* opacity: 1;
  z-index: 100000; */
}

:deep(.my-toolbar-item2) {
  top: 31px;
  left: 730px;
  /* opacity: 1;
  z-index: 100000; */
}

:deep(.my-dropdown) {
  position: fixed;
}

:deep(.my-menu-item) {
  height: 30px;
  width: 200px;
  font-size: 14px;
  background-color: #fff;
}

:deep(.my-menu-item:hover) {
  background-color: #f2f6f8;
}
</style>